﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OpenGL
{
	public class GLGraph
	{
		public GLGraph()
		{
		}

		public virtual void Process(double dt)
		{

		}
	}

	public class GLSeries : GL
	{
		public GLText T;
		public IntPtr ObjPTR;
		public List<PT1> Values = new List<PT1>();
		public List<PT1_V3D> Colors = new List<PT1_V3D>();

		public GLSeries(params double[] values)
		{
			ObjPTR = GL.gluNewQuadric();
			T = new GLText("Arial");
			foreach (var x in values)
			{
				Values.Add(new PT1(0.1, 1, x));
				Colors.Add(new PT1_V3D(0.1, 1, V3D.White));
			}
		}

		public virtual void Process(double dt)
		{
			foreach (var X in Values)
				X.Process(dt);
			foreach (var X in Colors)
				X.Process(dt);
		}
		public double this[int I]
		{
			get
			{
				return Values[I].Value;
			}
			set
			{
				Values[I].Set(value);
			}
		}
		public void SetColorValue(int N, V3D col, double val)
		{
			Colors[N].Set(col);
			Values[N].Set(val);
		}

		public void DrawLines()
		{
			glBegin(GL_LINE_STRIP);
			foreach (var X in Values)
				glV3D(new V3D(0, X.Value, 0));
			glEnd();
		}
		public void DrawColumns(double ColumnGap, double ColumnWidth, double HeightScale)
		{
			for (int i = 0; i < Values.Count; i++)
			{
				glPushAttrib(GL_ALL_ATTRIB_BITS);
				glEnable(GL_COLOR_MATERIAL);

				glEnable(GL_LIGHTING);
				//SetLight(0, 5, 0, 0, 1, 0, 0);

				float A = 0.2f;
				float D = 0.8f;
				glLightfv(GL_LIGHT0, GL_AMBIENT, A, A, A, 1);
				glLightfv(GL_LIGHT0, GL_DIFFUSE, D, D, D, 1);

				glEnable(GL_LIGHT0);
				//GL.gluQuadricNormals(ObjPTR, GLU_SMOOTH);
				glLightfv(GL_LIGHT0, GL_POSITION, 100, 0, 100, 1);
				glPushMatrix();
				glTrans3D(V3D.Red * ColumnGap * (i - (Values.Count - 1) / 2.0));

				GL.glCol3D(Colors[i].Value);
				T.DrawString((Values[i].Value * 100).ToString("0.00") + "%", 0, Values[i].Value * HeightScale, 0.2, 0.15, System.Drawing.StringAlignment.Center);

				glRotated(90, -1, 0, 0);
				if (i >= Colors.Count)
					glCol3D(V3D.White);
				glCol3D(Colors[i].Value);

				gluCylinder(ObjPTR, ColumnWidth, ColumnWidth, HeightScale * Values[i].Value, 32, 2);
				glPopMatrix();
				GL.glPopAttrib();
			}
		}

		public void DrawPie(double Size, double Height)
		{
			double T = 0;
			for (int i = 0; i < Values.Count; i++)
				T += Values[i].Value;

			double Angle = 134 / 199.0 * 360;
			glCol3D(V3D.Red);
			gluPartialDisk(ObjPTR, 0, Size, 64, 2, 0, Angle);
			glCol3D(V3D.Green);
			gluPartialDisk(ObjPTR, 0, Size, 64, 2, Angle, 360 - Angle);

			double sa = 0;
			for (int i = 0; i < Values.Count; i++)
			{
				double sw = Values[i].Value / T * 360;

				glPushAttrib(GL_ALL_ATTRIB_BITS);
				glEnable(GL_COLOR_MATERIAL);

				glEnable(GL_LIGHTING);
				//SetLight(0, 5, 0, 0, 1, 0, 0);

				float A = 0.2f;
				float D = 0.8f;
				glLightfv(GL_LIGHT0, GL_AMBIENT, A, A, A, 1);
				glLightfv(GL_LIGHT0, GL_DIFFUSE, D, D, D, 1);

				glEnable(GL_LIGHT0);
				//GL.gluQuadricNormals(ObjPTR, GLU_SMOOTH);
				glLightfv(GL_LIGHT0, GL_POSITION, 100, 0, 100, 1);
				glPushMatrix();
				if (i >= Colors.Count)
					glCol3D(V3D.Black);
				else
					glCol3D(Colors[i].Value);
				gluPartialDisk(ObjPTR, Size * 3 / 4, Size, 32, 2, sa, sw);
				sa += sw;
				glPopMatrix();
				GL.glPopAttrib();
			}
		}

		public void DrawLines(int X, int Y, double XScale, double YScale, V3D C, int max = -1)
		{
			GL.glPushMatrix();
			GL.glTranslated(X, Y, 0);
			GL.glBegin(GL.GL_LINE_STRIP);
			GL.glCol3D(C);
			int N = 0;
			for (int i = max == -1 ? 0 : Math.Max(0, Values.Count - max); i < Values.Count; i++)
			{
				GL.glVertex3d(XScale * N, Values[i].Value * YScale, 0);
				N++;
			}
			GL.glEnd();
			GL.glPopMatrix();
		}
	}
}